#ifndef __GlDxSprite_h__
#define __GlDxSprite_h__

#include <d3d11.h>

#include "GlDxGraphicComponent.h"
#include "GlPosition.h"
#include "GlSize.h"
#include "GlSprite.h"

namespace GraphicLibrary
{
	class Matrix4x4;
	class Position;
	class SpriteDescription;

#	pragma warning(disable: 4250)
	
	class DxSprite
		: public Sprite
		, public DxGraphicComponent
	{
		public:
			enum ExceptionList
			{
				ElSpriteNameNotFound
			};

			DxSprite(ID3D11Device *device, const char *spriteName);
			virtual ~DxSprite();
			virtual void setTransparency(const float value);
			virtual float getTransparency() const;
			virtual Size getSize() const;
			virtual void setSize(const Size &newSize);
			virtual void setScale(const Size &newScale);
			virtual Size getScale() const;
			virtual bool contains(const Position &pos) const;
			virtual void tick(const float deltaTime);
			virtual Matrix4x4 getTransformationMatrix() const;
			virtual void apply(ID3D11DeviceContext *ic) const;
			Position getUvShift() const;
			Size getTextureRelativeFrameSize() const;
			float getBoundingCircleRadius() const;

			void fillVertexes(Position *vertexes) const;

			inline const Size& getSizeMul() const		{return mSizeMul;}
			inline const Size& getTextureSize() const	{return mTextureSize;}
			inline Size getTexelSize() const			{return Size(1.0f / mTextureSize.mWidth, 1.0f / mTextureSize.mHeight);}

			inline static void Init(ID3D11Device *device)	{Sprite::Init(new DxFactory(device));}
		private:
			class DxFactory
				: public Factory
			{
				public:
					inline DxFactory(ID3D11Device *device)
						: mDevice(device)
					{}
					virtual ~DxFactory();
					virtual Sprite* create(const char *spriteName);
				private:
					ID3D11Device*	mDevice;
			};

			Size		mTextureSize;
			unsigned	mFrameIndex;
			float		mTimeSinceFrameStarted;
			bool		mDoAnimation;
			Size		mSizeMul;
			Size		mScale;
			float		mTransparency;

			const SpriteDescription*	mDesc;
			ID3D11Buffer*				mVertexBuffer;
			ID3D11Buffer*				mIndexBuffer;
			ID3D11ShaderResourceView*	mTexture;

			ID3D11Buffer* createVertexBuffer(ID3D11Device *device) const;
			ID3D11Buffer* createIndexBuffer(ID3D11Device *device) const;
			void initTexture(const char *fileName);

			Matrix4x4 getInvTransformationMatrix() const;
	};

#	pragma warning(default: 4250)
}

#endif // __GlDxSprite_h__
